package com.westdream;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import com.westdream.action.Action;
import com.westdream.config.ActionConfig;
import com.westdream.config.Configuration;
import com.westdream.config.FormConfig;
import com.westdream.config.PropertyConfig;
import com.westdream.config.ResultConfig;


public class ActionServlet extends HttpServlet {

	private static final long serialVersionUID = 5852463410268904006L;
	/** 配置文件，默认为CLASSPATH **/
	public static final String CONFIG_FILE = "configure.xml";
	private Configuration config = null;
	
	public ActionServlet() {

	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		process(request, response);
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		process(request, response);
	}

	@Override
	public void init() throws ServletException {
		initConfig();
	}

	protected void process(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String requestURI = request.getRequestURI();
		ActionConfig actionConfig = config.getActionMappings().get(parseURI(requestURI));
		try {
			Action act = (Action)Class.forName(actionConfig.getClassName()).newInstance();
			Object data = null;
			if(actionConfig.getName() != null) {
				data = getFormObject(config.getFormMappings().get(actionConfig.getName()),request);
			}
			String result = act.execute(request, response, data);
			ResultConfig resultConfig = actionConfig.getResults().get(result);
			request.getRequestDispatcher(resultConfig.getPath()).forward(request, response);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} 
	}

	protected void initConfig() {
		 config = Configuration.newInstance().configure(getServletContext());
	}

	@Override
	public void destroy() {
	
	}
	
	/** 解析URI **/
	protected String parseURI(String uri) {
		return uri.substring(0, uri.lastIndexOf("."));
	}

	/** 将form表单的数据封装成相应的Object **/
	protected Object getFormObject(FormConfig formConfig, HttpServletRequest request) {
		/** 如果配置相应的表单，则返回空 **/
		if(formConfig == null)
			return null;
		List<PropertyConfig> props = formConfig.getProperties();
		Object obj = null;
		 try {
			obj  = Class.forName(formConfig.getClassName()).newInstance();
			for(PropertyConfig prop : props) {
				StringBuilder methodName = new StringBuilder("set" + prop.getName());
				methodName.setCharAt(3, Character.toUpperCase(methodName.charAt(3)));
				Class<?> typeClass = Class.forName(prop.getType());
				Method method = obj.getClass().getMethod(methodName.toString(), typeClass);
				method.invoke(obj, new Object[]{request.getParameter(prop.getName())});
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
		return obj;
	}
}
